<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
  <title>Dynamic clusters</title>
  <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css"
    crossorigin="anonymous">
  <link rel="stylesheet" type="text/css"
    href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.1.2/css/fontawesome.min.css"
    crossorigin="anonymous">
  <link rel="stylesheet" type="text/css"
    href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.1.2/css/solid.css" crossorigin="anonymous">
  <link rel="stylesheet" type="text/css"
    href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.1.2/css/brands.css" crossorigin="anonymous">
  <link rel="stylesheet" type="text/css" href="./theme/ol.css">
  <link rel="stylesheet" type="text/css" href="/theme/site.css">
  <link rel="icon" type="image/svg+xml" href="/theme/img/logo-light.svg" media="(prefers-color-scheme: light)" />
  <link rel="icon" type="image/svg+xml" href="/theme/img/logo-dark.svg" media="(prefers-color-scheme: dark)" />
</head>

<body>
  <header class="navbar navbar-expand-md navbar-dark mb-3 px-3 py-0 fixed-top" role="navigation">
    <a class="navbar-brand" href="/"><img src="/theme/img/logo-dark.svg" width="70" height="70"
        alt="">&nbsp;OpenLayers</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#olmenu"
      aria-controls="olmenu" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>

    <!-- menu items that get hidden below 768px width -->
    <nav class="collapse navbar-collapse" id="olmenu">
      <ul class="nav navbar-nav ms-auto">
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" href="#" id="docdropdown" role="button" data-bs-toggle="dropdown"
            aria-haspopup="true" aria-expanded="false">Docs</a>
          <div class="dropdown-menu dropdown-menu-end mb-3" aria-labelledby="docdropdown">
            <a class="dropdown-item" href="/doc/">Docs</a>
            <div class="dropdown-divider"></div>
            <a class="dropdown-item" href="/doc/quickstart.html"><i class="fa fa-check fa-fw me-2 fa-lg"></i>快速入门</a>
            <a class="dropdown-item" href="/doc/faq.html"><i class="fa fa-question fa-fw me-2 fa-lg"></i>常见问题</a>
            <a class="dropdown-item" href="/doc/tutorials/"><i class="fa fa-book fa-fw me-2 fa-lg"></i>教程</a>

          </div>
        </li>
        <li class="nav-item"><a class="nav-link" href="/en/latest/examples/">Examples</a></li>
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" href="#" id="apidropdown" role="button" data-bs-toggle="dropdown"
            aria-haspopup="true" aria-expanded="false">
            <i class="fa fa-sitemap me-1"></i>API
          </a>
          <div class="dropdown-menu dropdown-menu-end mb-3" aria-labelledby="apidropdown">
            <a class="dropdown-item" href="/en/latest/apidoc/"><i class="fa fa-sitemap fa-fw me-2 fa-lg"></i>v8.2.0
              (latest)</a </div>
        </li>
      </ul>
    </nav>
  </header>

  <div class="container-fluid line-numbers">
    <div id="latest-check" class="alert alert-warning alert-dismissible" role="alert" style="display:none">
      <button id="latest-dismiss" type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
      This example uses OpenLayers v<span>8.2.0</span>. The <a id="latest-link" href="#" class="alert-link">latest</a>
      is v<span id="latest-version"></span>.
    </div>


    <div class="row-fluid">
      <a href="#" id="codepen-button" class="btn btn-link float-end">
        <i class="fab fa-codepen fa-lg"></i> Edit
      </a>
      <div class="span12">
        <h4 id="title">Dynamic clusters</h4>
        <p class="tags">
          <span class="badge-group">
            <a href="./index.html?q=marker" class="badge badge-info">marker</a><a
              class="badge badge-info tag-modal-toggle" data-bs-toggle="modal" data-bs-target="#tag-example-list"
              data-title="marker" data-content="&lt;ul class=&quot;list-group&quot;&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action active&quot; href=&quot;./clusters-dynamic.html&quot;&gt;Dynamic clusters&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./icon-color.html&quot;&gt;Icon Colors&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./modify-icon.html&quot;&gt;Icon modification&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./icon-negative.html&quot;&gt;Icon Pixel Operations&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./icon.html&quot;&gt;Icon Symbolizer&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./icon-width.html&quot;&gt;Icon Symbolizer width and height&lt;/a&gt;
                  &lt;/ul&gt;" tabindex="0">6</a>
          </span>
          <span class="badge-group">
            <a href="./index.html?q=cluster" class="badge badge-info">cluster</a><a
              class="badge badge-info tag-modal-toggle" data-bs-toggle="modal" data-bs-target="#tag-example-list"
              data-title="cluster" data-content="&lt;ul class=&quot;list-group&quot;&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./cluster.html&quot;&gt;Clustered Features&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action active&quot; href=&quot;./clusters-dynamic.html&quot;&gt;Dynamic clusters&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./earthquake-clusters.html&quot;&gt;Earthquake Clusters&lt;/a&gt;
                  &lt;/ul&gt;" tabindex="0">3</a>
          </span>
          <span class="badge-group">
            <a href="./index.html?q=vector" class="badge badge-info">vector</a><a
              class="badge badge-info tag-modal-toggle" data-bs-toggle="modal" data-bs-target="#tag-example-list"
              data-title="vector" data-content="&lt;ul class=&quot;list-group&quot;&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./mapbox-vector-tiles-advanced.html&quot;&gt;Advanced Mapbox Vector Tiles&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./animated-gif.html&quot;&gt;Animated GIF&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./vector-esri.html&quot;&gt;ArcGIS REST Feature Service&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./cluster.html&quot;&gt;Clustered Features&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./feature-animation.html&quot;&gt;Custom Animation&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./custom-circle-render.html&quot;&gt;Custom Circle Render&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./custom-hit-detection-renderer.html&quot;&gt;Custom Hit Detection Render&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./custom-interactions.html&quot;&gt;Custom Interactions&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./polygon-styles.html&quot;&gt;Custom Polygon Styles&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./declutter-group.html&quot;&gt;Declutter Group&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./drag-and-drop-image-vector.html&quot;&gt;Drag-and-Drop Image Vector&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./draw-and-modify-features.html&quot;&gt;Draw and Modify Features&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./draw-and-modify-geodesic.html&quot;&gt;Draw and Modify Geodesic Circles&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./draw-features.html&quot;&gt;Draw Features&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./webgl-draw-line.html&quot;&gt;Draw lines rendered with WebGL&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./draw-shapes.html&quot;&gt;Draw Shapes&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action active&quot; href=&quot;./clusters-dynamic.html&quot;&gt;Dynamic clusters&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./earthquake-clusters.html&quot;&gt;Earthquake Clusters&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./heatmap-earthquakes.html&quot;&gt;Earthquakes Heatmap&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./kml-earthquakes.html&quot;&gt;Earthquakes in KML&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./earthquake-custom-symbol.html&quot;&gt;Earthquakes with custom symbols&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./vector-esri-edit.html&quot;&gt;Editable ArcGIS REST Feature Service&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./flight-animation.html&quot;&gt;Flight Animation&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./fractal.html&quot;&gt;Fractal Rendering&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./draw-freehand.html&quot;&gt;Freehand Drawing&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./geojson.html&quot;&gt;GeoJSON&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./geojson-vt.html&quot;&gt;geojson-vt integration&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./icon-scale.html&quot;&gt;Icon and Label Scale&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./icon-color.html&quot;&gt;Icon Colors&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./modify-icon.html&quot;&gt;Icon modification&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./icon-negative.html&quot;&gt;Icon Pixel Operations&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./icon.html&quot;&gt;Icon Symbolizer&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./icon-width.html&quot;&gt;Icon Symbolizer width and height&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./jsts.html&quot;&gt;JSTS Integration&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./line-arrows.html&quot;&gt;LineString Arrows&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./mapbox-vector-layer.html&quot;&gt;Mapbox Vector Layer&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./mapbox-vector-tiles.html&quot;&gt;Mapbox Vector Tiles&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./mapbox-layer.html&quot;&gt;Mapbox-gl Layer&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./measure.html&quot;&gt;Measure&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./measure-style.html&quot;&gt;Measure using vector styles&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./modify-features.html&quot;&gt;Modify Features&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./modify-test.html&quot;&gt;Modify Features Test&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./ogc-vector-tiles.html&quot;&gt;OGC Vector Tiles&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./osm-vector-tiles.html&quot;&gt;OSM Vector Tiles&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./vector-osm.html&quot;&gt;OSM XML&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./populated-places.html&quot;&gt;Populated Places&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./regularshape.html&quot;&gt;Regular Shapes&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./rich-text-labels.html&quot;&gt;Rich Text Labels&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./modify-scale-and-rotate.html&quot;&gt;Scale and Rotate using Modify Interaction&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./select-features.html&quot;&gt;Select Features&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./select-hover-features.html&quot;&gt;Select Features by Hover&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./select-multiple-features.html&quot;&gt;Select multiple Features&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./snap.html&quot;&gt;Snap Interaction&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./street-labels.html&quot;&gt;Street Labels&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./style-expressions.html&quot;&gt;Style Expressions&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./style-renderer.html&quot;&gt;Style renderer&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./synthetic-lines.html&quot;&gt;Synthetic Lines&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./synthetic-points.html&quot;&gt;Synthetic Points&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./kml-timezones.html&quot;&gt;Timezones in KML&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./tooltip-on-hover.html&quot;&gt;Tooltip on Hover&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./topojson.html&quot;&gt;TopoJSON&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./topolis.html&quot;&gt;topolis integration&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./tracing.html&quot;&gt;Tracing around a polygon&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./translate-features.html&quot;&gt;Translate Features&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./turf.html&quot;&gt;turf.js&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./layer-clipping-vector.html&quot;&gt;Vector Clipping Layer&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./image-vector-layer.html&quot;&gt;Vector Image Layer&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./vector-label-decluttering.html&quot;&gt;Vector Label Decluttering&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./vector-labels.html&quot;&gt;Vector Labels&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./vector-labels-justify-text.html&quot;&gt;Vector Labels - Justify Text&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./vector-layer.html&quot;&gt;Vector Layer&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./hitdetect-vector.html&quot;&gt;Vector Layer Hit Detection&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./webgl-vector-layer.html&quot;&gt;WebGL Vector Layer&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./webgl-vector-tiles.html&quot;&gt;WebGL Vector Tiles Layer&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./vector-wfs.html&quot;&gt;WFS&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./vector-wfs-getfeature.html&quot;&gt;WFS - GetFeature&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./vector-wfs-geographic.html&quot;&gt;WFS with geographic coordinates&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./wind-arrows.html&quot;&gt;Wind Arrows&lt;/a&gt;
                  &lt;/ul&gt;" tabindex="0">78</a>
          </span>
          <span class="badge-group">
            <a href="./index.html?q=style" class="badge badge-info">style</a><a
              class="badge badge-info tag-modal-toggle" data-bs-toggle="modal" data-bs-target="#tag-example-list"
              data-title="style" data-content="&lt;ul class=&quot;list-group&quot;&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./animated-gif.html&quot;&gt;Animated GIF&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./cog-stretch.html&quot;&gt;Band Contrast Stretch&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./cog-style.html&quot;&gt;Change Tile Layer Style&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./polygon-styles.html&quot;&gt;Custom Polygon Styles&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./draw-features-style.html&quot;&gt;Drawing Features Style&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action active&quot; href=&quot;./clusters-dynamic.html&quot;&gt;Dynamic clusters&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./earthquake-clusters.html&quot;&gt;Earthquake Clusters&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./heatmap-earthquakes.html&quot;&gt;Earthquakes Heatmap&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./kml-earthquakes.html&quot;&gt;Earthquakes in KML&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./earthquake-custom-symbol.html&quot;&gt;Earthquakes with custom symbols&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./geotiff-reprojection.html&quot;&gt;GeoTIFF Reprojection&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./icon-scale.html&quot;&gt;Icon and Label Scale&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./icon-color.html&quot;&gt;Icon Colors&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./icon-negative.html&quot;&gt;Icon Pixel Operations&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./icon.html&quot;&gt;Icon Symbolizer&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./icon-width.html&quot;&gt;Icon Symbolizer width and height&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./measure-style.html&quot;&gt;Measure using vector styles&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./regularshape.html&quot;&gt;Regular Shapes&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./style-expressions.html&quot;&gt;Style Expressions&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./style-renderer.html&quot;&gt;Style renderer&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./canvas-gradient-pattern.html&quot;&gt;Styling feature with CanvasGradient or CanvasPattern&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./kml-timezones.html&quot;&gt;Timezones in KML&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./topojson.html&quot;&gt;TopoJSON&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./webgl-tile-style.html&quot;&gt;WebGL Tile Layer Styles&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./wind-arrows.html&quot;&gt;Wind Arrows&lt;/a&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action&quot; href=&quot;./zoomslider.html&quot;&gt;Zoom Sliders&lt;/a&gt;
                  &lt;/ul&gt;" tabindex="0">26</a>
          </span>
          <span class="badge-group">
            <a href="./index.html?q=convexhull" class="badge badge-info">convexhull</a><a
              class="badge badge-info tag-modal-toggle" data-bs-toggle="modal" data-bs-target="#tag-example-list"
              data-title="convexhull" data-content="&lt;ul class=&quot;list-group&quot;&gt;
                  &lt;li&gt;&lt;a class=&quot;list-group-item list-group-item-action active&quot; href=&quot;./clusters-dynamic.html&quot;&gt;Dynamic clusters&lt;/a&gt;
                  &lt;/ul&gt;" tabindex="0">1</a>
          </span>
        </p>
        <div class="modal modal-tag-example" id="tag-example-list" tabindex="-1" role="dialog"
          aria-labelledby="tag-example-title" aria-hidden="true">
          <div class="modal-dialog modal-dialog-scrollable" role="document">
            <div class="modal-content">
              <div class="modal-header">
                <h5 class="modal-title" id="tag-example-title"></h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
              </div>
              <div class="modal-body">
                <div class="list-group"></div>
              </div>
            </div>
          </div>
        </div>
        <div id="map" class="map"></div>

      </div>
      <form method="POST" id="codepen-form" target="_blank" action="https://codesandbox.io/api/v1/sandboxes/define">
        <input id="codesandbox-params" type="hidden" name="parameters">
      </form>
    </div>

    <div class="row-fluid">
      <div class="span12">
        <p id="shortdesc">Clusters with zoom-to-cluster, hull view, and uncluttering of overlapping features.</p>
        <div id="docs">
          <p>
            这个示例展示了维也纳补贴光伏安装设施的开放数据。使用不同的样式函数进行集群显示、单个特征显示、集群的凸包以及重叠特征的扩展视图。将鼠标悬停在集群上时，将显示其凸包。单击集群将缩放到所包含特征的范围内。单击由彼此非常接近的特征组成的集群时，将沿着集群周围的圆形显示特征的扩展视图。
          </p>
          <p>光伏安装设施的样式会根据其功率的不同而有所不同。</p>
        </div>
      </div>
    </div>

    <div class="row-fluid">
      <h5 class="source-heading">main.js</h5>
      <pre><code id="example-js-source" class="language-js">import Feature from &#x27;ol/Feature.js&#x27;;
import GeoJSON from &#x27;ol/format/GeoJSON.js&#x27;;
import Map from &#x27;ol/Map.js&#x27;;
import View from &#x27;ol/View.js&#x27;;
import {
  Circle as CircleStyle,
  Fill,
  Icon,
  Stroke,
  Style,
  Text,
} from &#x27;ol/style.js&#x27;;
import {Cluster, Vector as VectorSource, XYZ} from &#x27;ol/source.js&#x27;;
import {LineString, Point, Polygon} from &#x27;ol/geom.js&#x27;;
import {Tile as TileLayer, Vector as VectorLayer} from &#x27;ol/layer.js&#x27;;
import {createEmpty, extend, getHeight, getWidth} from &#x27;ol/extent.js&#x27;;
import {fromLonLat} from &#x27;ol/proj.js&#x27;;

const circleDistanceMultiplier &#x3D; 1;
const circleFootSeparation &#x3D; 28;
const circleStartAngle &#x3D; Math.PI / 2;

const convexHullFill &#x3D; new Fill({
  color: &#x27;rgba(255, 153, 0, 0.4)&#x27;,
});
const convexHullStroke &#x3D; new Stroke({
  color: &#x27;rgba(204, 85, 0, 1)&#x27;,
  width: 1.5,
});
const outerCircleFill &#x3D; new Fill({
  color: &#x27;rgba(255, 153, 102, 0.3)&#x27;,
});
const innerCircleFill &#x3D; new Fill({
  color: &#x27;rgba(255, 165, 0, 0.7)&#x27;,
});
const textFill &#x3D; new Fill({
  color: &#x27;#fff&#x27;,
});
const textStroke &#x3D; new Stroke({
  color: &#x27;rgba(0, 0, 0, 0.6)&#x27;,
  width: 3,
});
const innerCircle &#x3D; new CircleStyle({
  radius: 14,
  fill: innerCircleFill,
});
const outerCircle &#x3D; new CircleStyle({
  radius: 20,
  fill: outerCircleFill,
});
const darkIcon &#x3D; new Icon({
  src: &#x27;data/icons/emoticon-cool.svg&#x27;,
});
const lightIcon &#x3D; new Icon({
  src: &#x27;data/icons/emoticon-cool-outline.svg&#x27;,
});

/**
 * Single feature style, users for clusters with 1 feature and cluster circles.
 * @param {Feature} clusterMember A feature from a cluster.
 * @return {Style} An icon style for the cluster member&#x27;s location.
 */
function clusterMemberStyle(clusterMember) {
  return new Style({
    geometry: clusterMember.getGeometry(),
    image: clusterMember.get(&#x27;LEISTUNG&#x27;) &gt; 5 ? darkIcon : lightIcon,
  });
}

let clickFeature, clickResolution;
/**
 * Style for clusters with features that are too close to each other, activated on click.
 * @param {Feature} cluster A cluster with overlapping members.
 * @param {number} resolution The current view resolution.
 * @return {Style|null} A style to render an expanded view of the cluster members.
 */
function clusterCircleStyle(cluster, resolution) {
  if (cluster !&#x3D;&#x3D; clickFeature || resolution !&#x3D;&#x3D; clickResolution) {
    return null;
  }
  const clusterMembers &#x3D; cluster.get(&#x27;features&#x27;);
  const centerCoordinates &#x3D; cluster.getGeometry().getCoordinates();
  return generatePointsCircle(
    clusterMembers.length,
    cluster.getGeometry().getCoordinates(),
    resolution
  ).reduce((styles, coordinates, i) &#x3D;&gt; {
    const point &#x3D; new Point(coordinates);
    const line &#x3D; new LineString([centerCoordinates, coordinates]);
    styles.unshift(
      new Style({
        geometry: line,
        stroke: convexHullStroke,
      })
    );
    styles.push(
      clusterMemberStyle(
        new Feature({
          ...clusterMembers[i].getProperties(),
          geometry: point,
        })
      )
    );
    return styles;
  }, []);
}

/**
 * From
 * https://github.com/Leaflet/Leaflet.markercluster/blob/31360f2/src/MarkerCluster.Spiderfier.js#L55-L72
 * Arranges points in a circle around the cluster center, with a line pointing from the center to
 * each point.
 * @param {number} count Number of cluster members.
 * @param {Array&lt;number&gt;} clusterCenter Center coordinate of the cluster.
 * @param {number} resolution Current view resolution.
 * @return {Array&lt;Array&lt;number&gt;&gt;} An array of coordinates representing the cluster members.
 */
function generatePointsCircle(count, clusterCenter, resolution) {
  const circumference &#x3D;
    circleDistanceMultiplier * circleFootSeparation * (2 + count);
  let legLength &#x3D; circumference / (Math.PI * 2); //radius from circumference
  const angleStep &#x3D; (Math.PI * 2) / count;
  const res &#x3D; [];
  let angle;

  legLength &#x3D; Math.max(legLength, 35) * resolution; // Minimum distance to get outside the cluster icon.

  for (let i &#x3D; 0; i &lt; count; ++i) {
    // Clockwise, like spiral.
    angle &#x3D; circleStartAngle + i * angleStep;
    res.push([
      clusterCenter[0] + legLength * Math.cos(angle),
      clusterCenter[1] + legLength * Math.sin(angle),
    ]);
  }

  return res;
}

let hoverFeature;
/**
 * Style for convex hulls of clusters, activated on hover.
 * @param {Feature} cluster The cluster feature.
 * @return {Style|null} Polygon style for the convex hull of the cluster.
 */
function clusterHullStyle(cluster) {
  if (cluster !&#x3D;&#x3D; hoverFeature) {
    return null;
  }
  const originalFeatures &#x3D; cluster.get(&#x27;features&#x27;);
  const points &#x3D; originalFeatures.map((feature) &#x3D;&gt;
    feature.getGeometry().getCoordinates()
  );
  return new Style({
    geometry: new Polygon([monotoneChainConvexHull(points)]),
    fill: convexHullFill,
    stroke: convexHullStroke,
  });
}

function clusterStyle(feature) {
  const size &#x3D; feature.get(&#x27;features&#x27;).length;
  if (size &gt; 1) {
    return [
      new Style({
        image: outerCircle,
      }),
      new Style({
        image: innerCircle,
        text: new Text({
          text: size.toString(),
          fill: textFill,
          stroke: textStroke,
        }),
      }),
    ];
  }
  const originalFeature &#x3D; feature.get(&#x27;features&#x27;)[0];
  return clusterMemberStyle(originalFeature);
}

const vectorSource &#x3D; new VectorSource({
  format: new GeoJSON(),
  url: &#x27;data/geojson/photovoltaic.json&#x27;,
});

const clusterSource &#x3D; new Cluster({
  attributions:
    &#x27;Data: &lt;a href&#x3D;&quot;https://www.data.gv.at/auftritte/?organisation&#x3D;stadt-wien&quot;&gt;Stadt Wien&lt;/a&gt;&#x27;,
  distance: 35,
  source: vectorSource,
});

// Layer displaying the convex hull of the hovered cluster.
const clusterHulls &#x3D; new VectorLayer({
  source: clusterSource,
  style: clusterHullStyle,
});

// Layer displaying the clusters and individual features.
const clusters &#x3D; new VectorLayer({
  source: clusterSource,
  style: clusterStyle,
});

// Layer displaying the expanded view of overlapping cluster members.
const clusterCircles &#x3D; new VectorLayer({
  source: clusterSource,
  style: clusterCircleStyle,
});

const raster &#x3D; new TileLayer({
  source: new XYZ({
    attributions:
      &#x27;Base map: &lt;a target&#x3D;&quot;_blank&quot; href&#x3D;&quot;https://basemap.at/&quot;&gt;basemap.at&lt;/a&gt;&#x27;,
    url: &#x27;https://maps{1-4}.wien.gv.at/basemap/bmapgrau/normal/google3857/{z}/{y}/{x}.png&#x27;,
  }),
});

const map &#x3D; new Map({
  layers: [raster, clusterHulls, clusters, clusterCircles],
  target: &#x27;map&#x27;,
  view: new View({
    center: [0, 0],
    zoom: 2,
    maxZoom: 19,
    extent: [
      ...fromLonLat([16.1793, 48.1124]),
      ...fromLonLat([16.5559, 48.313]),
    ],
    showFullExtent: true,
  }),
});

map.on(&#x27;pointermove&#x27;, (event) &#x3D;&gt; {
  clusters.getFeatures(event.pixel).then((features) &#x3D;&gt; {
    if (features[0] !&#x3D;&#x3D; hoverFeature) {
      // Display the convex hull on hover.
      hoverFeature &#x3D; features[0];
      clusterHulls.setStyle(clusterHullStyle);
      // Change the cursor style to indicate that the cluster is clickable.
      map.getTargetElement().style.cursor &#x3D;
        hoverFeature &amp;&amp; hoverFeature.get(&#x27;features&#x27;).length &gt; 1
          ? &#x27;pointer&#x27;
          : &#x27;&#x27;;
    }
  });
});

map.on(&#x27;click&#x27;, (event) &#x3D;&gt; {
  clusters.getFeatures(event.pixel).then((features) &#x3D;&gt; {
    if (features.length &gt; 0) {
      const clusterMembers &#x3D; features[0].get(&#x27;features&#x27;);
      if (clusterMembers.length &gt; 1) {
        // Calculate the extent of the cluster members.
        const extent &#x3D; createEmpty();
        clusterMembers.forEach((feature) &#x3D;&gt;
          extend(extent, feature.getGeometry().getExtent())
        );
        const view &#x3D; map.getView();
        const resolution &#x3D; map.getView().getResolution();
        if (
          view.getZoom() &#x3D;&#x3D;&#x3D; view.getMaxZoom() ||
          (getWidth(extent) &lt; resolution &amp;&amp; getHeight(extent) &lt; resolution)
        ) {
          // Show an expanded view of the cluster members.
          clickFeature &#x3D; features[0];
          clickResolution &#x3D; resolution;
          clusterCircles.setStyle(clusterCircleStyle);
        } else {
          // Zoom to the extent of the cluster members.
          view.fit(extent, {duration: 500, padding: [50, 50, 50, 50]});
        }
      }
    }
  });
});
</code></pre>
    </div>

    <div class="row-fluid">
      <h5 class="source-heading">index.html</h5>
      <pre><code id="example-html-source" class="language-markup">&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;title&gt;Dynamic clusters&lt;/title&gt;
    &lt;link rel="stylesheet" href="node_modules/ol/ol.css"&gt;
    &lt;style&gt;
      .map {
        width: 100%;
        height: 400px;
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id&#x3D;&quot;map&quot; class&#x3D;&quot;map&quot;&gt;&lt;/div&gt;

    &lt;script src="https://cdn.jsdelivr.net/npm/monotone-chain-convex-hull@1.0.0/lib/index.js"&gt;&lt;/script&gt;
    &lt;script type="module" src="main.js"&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>
    </div>

    <div class="row-fluid">
      <h5 class="source-heading">package.json</h5>
      <pre><code id="example-pkg-source" class="language-json">{
  &quot;name&quot;: &quot;clusters-dynamic&quot;,
  &quot;dependencies&quot;: {
    &quot;ol&quot;: &quot;8.2.0&quot;
  },
  &quot;devDependencies&quot;: {
    &quot;vite&quot;: &quot;^3.2.3&quot;
  },
  &quot;scripts&quot;: {
    &quot;start&quot;: &quot;vite&quot;,
    &quot;build&quot;: &quot;vite build&quot;
  }
}</code></pre>
    </div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/monotone-chain-convex-hull@1.0.0/lib/index.js"></script>
  <script src="common.js"></script>
  <script src="clusters-dynamic.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/components/prism-core.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/plugins/autoloader/prism-autoloader.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/plugins/toolbar/prism-toolbar.min.js"></script>
  <script
    src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/plugins/copy-to-clipboard/prism-copy-to-clipboard.js"></script>
  <script src="./resources/common.js"></script>
  <script>
    document.getElementById('tag-example-list')
      .addEventListener('show.bs.modal', function (event) {
        const button = event.relatedTarget; // Button that triggered the modal
        this.querySelector('.modal-title').innerText = button.dataset.title;
        this.querySelector('.modal-body').innerHTML = button.dataset.content;
      });
  </script>
  <script>
    const releaseUrl = 'https://cdn.jsdelivr.net/npm/ol/package.json';
    fetch(releaseUrl).then(function (response) {
      return response.json();
    }).then(function (json) {
      const latestVersion = json.version;
      document.getElementById('latest-version').innerHTML = latestVersion;
      const url = window.location.href;
      const branchSearch = url.match(/\/([^\/]*)\/examples\//);
      const storageKey = 'ol-dismissed=-' + latestVersion;
      const dismissed = localStorage.getItem(storageKey) === 'true';
      if (branchSearch && !dismissed && /^v[0-9\.]*$/.test(branchSearch[1]) && '8.2.0' != latestVersion) {
        const link = url.replace(branchSearch[0], '/latest/examples/');
        fetch(link, { method: 'head' }).then(function (response) {
          const a = document.getElementById('latest-link');
          a.href = response.status == 200 ? link : '../../latest/examples/';
        });
        const latestCheck = document.getElementById('latest-check');
        latestCheck.style.display = '';
        document.getElementById('latest-dismiss').onclick = function () {
          latestCheck.style.display = 'none';
          localStorage.setItem(storageKey, 'true');
        }
      }
    });
  </script>
</body>

</html>